//package com.dfs.parent.gray.rule;
//import cn.hutool.core.collection.CollUtil;
//import cn.hutool.core.util.StrUtil;
//import com.dfs.parent.common.core.constant.GrayConstant;
//import com.dfs.parent.common.core.context.GrayContextHolder;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.factory.ObjectProvider;
//import org.springframework.cloud.client.ServiceInstance;
//import org.springframework.cloud.client.loadbalancer.DefaultResponse;
//import org.springframework.cloud.client.loadbalancer.EmptyResponse;
//import org.springframework.cloud.client.loadbalancer.Request;
//import org.springframework.cloud.client.loadbalancer.Response;
//import org.springframework.cloud.loadbalancer.core.*;
//import reactor.core.publisher.Mono;
//
//import java.util.List;
//import java.util.concurrent.atomic.AtomicInteger;
//import java.util.stream.Collectors;
//
///**
// * @Description 灰度规则
// * @Author dahong
// * @Date 2024/2/18 10:31
// */
//@Slf4j
//public class GrayRoundRobinLoadBalancer extends RoundRobinLoadBalancer {
//    private ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;
//    private String serviceId;
//    private AtomicInteger position;
//
//    public GrayRoundRobinLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider, String serviceId) {
//        super(serviceInstanceListSupplierProvider, serviceId);
//        this.serviceId = serviceId;
//        this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;
//    }
//
//    public GrayRoundRobinLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider, String serviceId, int seedPosition) {
//        super(serviceInstanceListSupplierProvider, serviceId, seedPosition);
//        this.serviceId = serviceId;
//        this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;
//        this.position = new AtomicInteger(seedPosition);
//    }
//    @Override
//    public Mono<Response<ServiceInstance>> choose(Request request) {
//        ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider
//                .getIfAvailable(NoopServiceInstanceListSupplier::new);
//        return supplier.get(request).next()
//                .map(serviceInstances -> processInstanceResponse(supplier, serviceInstances));
//    }
//    private Response<ServiceInstance> processInstanceResponse(ServiceInstanceListSupplier supplier,
//                                                              List<ServiceInstance> serviceInstances) {
//        Response<ServiceInstance> serviceInstanceResponse = getInstanceResponse(serviceInstances);
//        if (supplier instanceof SelectedInstanceCallback && serviceInstanceResponse.hasServer()) {
//            ((SelectedInstanceCallback) supplier).selectedServiceInstance(serviceInstanceResponse.getServer());
//        }
//        return serviceInstanceResponse;
//    }
//    private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances) {
//        if (instances.isEmpty()) {
//            if (log.isWarnEnabled()) {
//                log.warn("No servers available for service: " + serviceId);
//            }
//            return new EmptyResponse();
//        }
//
//        // Do not move position when there is only 1 instance, especially some suppliers
//        // have already filtered instances
//        if (instances.size() == 1) {
//            return new DefaultResponse(instances.get(0));
//        }
//        // 获取ServiceInstance列表
//        instances = getInstances(instances);
//
//        if (instances.size() == 1) {
//            return new DefaultResponse(instances.get(0));
//        }
//
//        // Ignore the sign bit, this allows pos to loop sequentially from 0 to
//        // Integer.MAX_VALUE
//        int pos = this.position.incrementAndGet() & Integer.MAX_VALUE;
//        ServiceInstance instance = instances.get(pos % instances.size());
//
//        return new DefaultResponse(instance);
//    }
//
//    private List<ServiceInstance> getInstances(List<ServiceInstance> instances) {
//        // 灰度标记不为空并且标记为true, 筛选ServiceInstance
//        List<ServiceInstance> chooseInstances = instances.stream()
//                .filter(instance -> StrUtil.isNotEmpty(instance.getMetadata().get(GrayConstant.GRAY_TAG))
//                        && GrayConstant.GRAY_TAG_VALUE_TRUE.equals(instance.getMetadata().get(GrayConstant.GRAY_TAG)))
//                .collect(Collectors.toList());
//        if (GrayConstant.GRAY_TAG_VALUE_TRUE.equals(GrayContextHolder.getGrayTag())) {
//            if(CollUtil.isEmpty(chooseInstances)){
//                return instances;
//            }
//            return chooseInstances;
//        } else {
//            instances.removeAll(chooseInstances);
//            return instances;
//        }
//    }
//}
